package cn.sytton.taffecloud.common.db.mybatis;

import cn.hutool.core.util.ReflectUtil;
import cn.sytton.taffecloud.common.base.util.SecurityUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;

import java.sql.Timestamp;
import java.util.Date;
import java.util.Properties;

/**
 * mybatis拦截器，自动更新4个日志字段
 *
 * @author skyrock
 */
@Intercepts({@Signature(type= Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
public class SqlUpdateInterceptor implements Interceptor {

    private static final String createdUserIdFiled = "createdUserId";
    private static final String createdTimeFiled = "createdTime";
    private static final String updatedUserIdFiled = "updatedUserId";
    private static final String updatedTimeFiled = "updatedTime";

    public Object intercept(Invocation invocation) throws Throwable {

        Object[] args = invocation.getArgs();
        if (args[1] == null){
            return invocation.proceed();
        }else{
            Object field = args[1];
            Class<?> cls = field.getClass();

            Timestamp now = (new Timestamp(new Date().getTime()));

            if (ReflectUtil.hasField(cls, createdUserIdFiled)) {
                if (ReflectUtil.getFieldValue(field, createdUserIdFiled) == null) {
                    ReflectUtil.setFieldValue(field, createdUserIdFiled, SecurityUtil.getUserId());
                }
            }
            if (ReflectUtil.hasField(cls, createdTimeFiled)) {
                if (ReflectUtil.getFieldValue(field, createdTimeFiled) == null) {
                    ReflectUtil.setFieldValue(field, createdTimeFiled, now);
                }
            }
            if ( ReflectUtil.hasField(cls, updatedUserIdFiled) ){
                ReflectUtil.setFieldValue(field, updatedUserIdFiled, SecurityUtil.getUserId());
            }
            if ( ReflectUtil.hasField(cls, updatedTimeFiled) ){
                ReflectUtil.setFieldValue(field, updatedTimeFiled, now);
            }

            return invocation.proceed();
        }
    }
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    public void setProperties(Properties properties) { }

}
